/**
 * 
 */
package com.momosw.games.engine.player;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.List;

import com.momosw.games.engine.EndTurnAction;
import com.momosw.games.engine.Option;
import com.momosw.games.engine.events.ActionEvent;
import com.momosw.games.engine.events.EndGameEvent;
import com.momosw.games.engine.events.Event;
import com.momosw.games.engine.events.FeedSupplyEvent;
import com.momosw.games.jericho.actions.DrawCardAction;
import com.momosw.games.jericho.actions.FeedSupplyAction;
import com.momosw.games.jericho.actions.PlayCardAction;
import com.momosw.games.jericho.board.Board;
import com.momosw.games.jericho.board.Deck;
import com.momosw.games.jericho.board.Scoring;

/**
 * <b>Project:</b> JerichoCardGame<br />
 * <b>Package:</b> com.momosw.games.engine<br />
 * <b>Class:</b> ConsolePlayer.java<br />
 * <br />
 * <i>GSI 2011</i><br />
 *
 * @author Miguel Coronado (miguelcb84@gmail.com)
 * @version	Aug 16, 2011
 *
 */
public class ConsolePlayer extends Player {

    private PrintWriter out;
    private BufferedReader in;
    
    public ConsolePlayer (String name) {
        super (name);
        out = new PrintWriter (new OutputStreamWriter(System.out));
        in = new BufferedReader( new InputStreamReader (System.in));
    }
    
    /* (non-Javadoc)
     * @see com.momosw.games.engine.Player#notify(java.lang.String)
     */
    @Override
    public void notify(String string) {
        out.println(string);
        out.flush();
    }
    
    @Override
    public void notify(Event event) {
        out.println(message(event));
        out.flush();
    }

    /** Generate a message according to the event */
    String message (Event event) {
        
        if (event instanceof EndTurnAction){
            if (((EndTurnAction)event).getPlayer().equals(this)){
                return "Has terminado tu turno";
            }
            return "";
        }
        
        if (event instanceof Board){
            Board board = (Board)event;
            if(board.getCurrentPlayer() == this){
                return "Es tu turno.\r" + board.getBoardInform();
            }
            // Do not inform about the state of the board in other players turns
            return "";
        }
        
        if (event instanceof DrawCardAction){
            ActionEvent aEvent = (DrawCardAction)event;
            if (aEvent.getPlayer().equals(this)){
                return "Has robado la carta " + aEvent.getCard();
            }
            if (aEvent.getCard() != null){
                return aEvent.getPlayer().getName() + " ha robado la carta " + aEvent.getCard().getReadableName();
            }
            return aEvent.getPlayer().getName() + " ha robado una carta";
        }
        
        if (event instanceof FeedSupplyAction){
            ActionEvent aEvent = (FeedSupplyAction)event;
            if (aEvent.getPlayer().equals(this)){
                return "Has colocado la carta " + aEvent.getCard().getReadableName() + " en la pila de suministros";
            }
            if (aEvent.getCard() != null){
                return aEvent.getPlayer().getName() + " ha colocado la carta " + aEvent.getCard().getReadableName() + " en la pila de suministros.";
            }
            return "Ha colocado una carta en la pila de suministros";
        }
        
        if (event instanceof PlayCardAction){
            ActionEvent aEvent = (PlayCardAction)event;
            String msg = "";
            if (aEvent.getPlayer().equals(this)){
                msg += "Has jugado la carta ";
            }
            else{
                msg += aEvent.getPlayer().getName() + " ha jugado la carta ";
            }
            if (aEvent.getWallType() != null){
                return msg + aEvent.getCard().getReadableName() + " en el muro " + aEvent.getWallType();
            }
            return msg + aEvent.getCard().getReadableName();
        }
        
        if (event instanceof FeedSupplyEvent){
            FeedSupplyEvent fsEvent = (FeedSupplyEvent)event;
            return "La carta " + fsEvent.getCard() + " ha sido colocada en la pila de suministros.";
        }
        
        if (event instanceof Deck){
            Deck deck = (Deck)event;
            return "\r\nEn la pila de suministros están las siguientes cartas: " + deck + "\r\n";
        }
        
        if (event instanceof Scoring){
            Scoring sco = (Scoring)event;
            return "\r\n\r\nLos resultados de la fase de puntuación han sido:\r\n" + sco.getScoringSummary() + "\r\n";
        }
        
        if (event instanceof EndGameEvent){
            EndGameEvent ege = (EndGameEvent)event;
            return "\r\n\r\nFin del juego:\r\n" + ege.getResults() + "\r\n";
        }
        System.err.println("Evento desconocido:" + event.getClass());
        return "Evento desconocido ";
        
    }
    
    @Override
    public Option chooseBetween (List<? extends Option> actions) {
        if (actions.size() == 1) {
            out.print(actions.get(0).getReadableName() + ":");
            return actions.get(0);
        }
        return chooseBetweenSomeOptions (actions);
    }
    
    /** */
    private Option chooseBetweenSomeOptions (List<? extends Option> actions) {
        out.println("Elige entre las siguientes opciones");
        for (int i = 1; i <= actions.size(); i++){
            out.println("\t" + i + ")" + actions.get(i-1).getReadableName());
        }
        out.flush();
        
        while(true) {
            try {
                int value = Integer.parseInt(in.readLine());
                return actions.get(value-1);
                
            } catch (IndexOutOfBoundsException e){
                out.println("Introduzca un número de entre los marcados.");
                out.flush();
            } catch (Exception e) {
                out.println("Introduzca la opción numérica que desee.");
                out.flush();
            }
        }
    }

}
